﻿/*
    MainDocument.as	
	Copyright (c) Otávio Ribeiro<otavio@otavio.eng.br> @ 2008
    
    This file is part of OtaSwfUploader application.

    Birthday is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Birthday is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package
{
    import flash.display.MovieClip;
    import flash.events.MouseEvent;
    import flash.text.TextFormat;
    import fl.controls.Button;
	import flash.external.ExternalInterface;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.system.Security;
	import flash.events.Event;
	import flash.events.DataEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.HTTPStatusEvent;
	import flash.events.ProgressEvent;
	import flash.events.IOErrorEvent;
	import flash.net.FileFilter;
	import flash.net.FileReferenceList;
	import flash.net.FileReference;
	
	import ExternalCall;
	import UploadFile;
    
    public class MainDocument extends MovieClip
    {
        private var b1:Button;
		private var p:Object;
		
		private var currentUploadFile:Number;
		
		private var pendingFiles:Array;
		
		private var externalCall:ExternalCall;
		
		/* private properties */
		private var buttonLabel:String;
		private var movieName:String;
		private var allowMultiplesFiles:Boolean;
		private var openFilters:Array;
		private var postUrl:String;
		private var imageFieldName:String;
		
		/* NOTIFY CONSTANTS */
		public static const NOTIFY_STATUS_ERROR:Number = 1;
		public static const NOTIFY_IO_ERROR:Number = 2;
		public static const NOTIFY_SECURITY_ERROR:Number = 3;
		public static const NOTIFY_OPEN:Number = 4;
		public static const NOTIFY_PROGRESS:Number = 5;
		public static const NOTIFY_COMPLETE:Number = 6;
		public static const NOTIFY_UPLOAD_COMPLETE:Number = 7;
		/* END NOTIFY CONSTANTS */
        
        public function MainDocument() 
		{
			
			Security.allowDomain("*");
			
			pendingFiles = new Array();
			currentUploadFile = -1;
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;

			setupExternalInterface();
			init();
			setupButton();
						
			this.externalCall = new ExternalCall(this.movieName);
			this.externalCall.dispatchOnInitPlugin();
		}
		
		private function setupExternalInterface():void 
		{
			ExternalInterface.addCallback("startUpload",startUpload);
			ExternalInterface.addCallback("addFileParameter",addFileParameter);
			ExternalInterface.addCallback("getNumberOfFiles",getNumberOfFiles);
			ExternalInterface.addCallback("getNumberOfPendingFiles",getNumberOfPendingFiles);
			ExternalInterface.addCallback("startNextPendingFile",startNextPendingFile);
			ExternalInterface.addCallback("getFileStatus",getFileStatus);
			ExternalInterface.addCallback("cancelFileUpload",cancelFileUpload);
			ExternalInterface.addCallback("addFileFilter",addFileFilter);
			ExternalInterface.addCallback("resetFiles",resetFiles);
		}
		
		private function init():void 
		{
			p = this.loaderInfo.parameters;
			
			buttonLabel = (p["buttonLabel"]?p["buttonLabel"]:"");
			movieName = (p["movieName"]?p["movieName"]:"");
			postUrl = (p["postUrl"]?p["postUrl"]:"");
			imageFieldName = (p["imageFieldName"]?p["imageFieldName"]:"image");
			allowMultiplesFiles = (p["allowMultiplesFiles"] && p["allowMultiplesFiles"].toLowerCase() == "true"?true:false);
			openFilters = [];
		}
		
        private function setupButton():void 
		{
            b1 = new Button();

            b1.move(0,0);

            b1.label = buttonLabel;
            b1.setStyle("textFormat", new TextFormat("Tahoma"));			
			b1.setStyle("upSkin","Button_upSkin");
			b1.setStyle("downSkin","Button_downSkin");
            b1.width = stage.stageWidth;
			b1.height = stage.stageHeight;
            b1.addEventListener(MouseEvent.CLICK,buttonClick);

            addChild(b1);
        }
		
		private function openFileDialogBox()
		{
			var c = this;
			var fn;
			
			if(this.allowMultiplesFiles){
				var fileList:FileReferenceList = new FileReferenceList();
				fn = function(ev:Event) {
					c.selectMultipleHandler(ev);
				}
				fileList.addEventListener(Event.SELECT, fn);
				fn = function(ev:Event) {
					c.cancelHandler(ev);
				}
				fileList.addEventListener(Event.CANCEL, fn);
				fileList.browse(openFilters);
			} else {
				var file:FileReference = new FileReference();
				
				fn = function(ev:Event) {
					c.selectHandler(ev);
				}
				file.addEventListener(Event.SELECT, fn);
				
				fn = function(ev:Event) {
					c.cancelHandler(ev);
				}
				file.addEventListener(Event.CANCEL, fn);
				file.browse(openFilters);
			}
		}
		
		private function addPendingFile(file:FileReference):void
		{
			 var pos = this.pendingFiles.length;
			 var uploadFile:UploadFile = new UploadFile(pos,file,this.postUrl, this.movieName, this.imageFieldName);
			 
			 this.pendingFiles.push(uploadFile);
			 this.externalCall.dispatchOnPendingFileAdded(uploadFile);
		}
		
		private function selectMultipleHandler(ev:Event):void
		{
			var fileList:FileReferenceList = FileReferenceList(ev.target);
			
			for(var i:uint; i < fileList.fileList.length; i++){
				var file:FileReference = FileReference(fileList.fileList[i]);				
				this.addPendingFile(file);
			}
		}
		
		private function selectHandler(ev:Event):void
		{
			var file:FileReference = FileReference(ev.target);
			this.addPendingFile(file);
		}
		
		private function cancelHandler(ev:Event):void
		{
		}
		
        private function buttonClick(e:MouseEvent) 
		{
            var button:Button = Button(e.target);
			this.openFileDialogBox();
        }
		
		public function getNumberOfFiles():Number
		{
			return this.pendingFiles.length;
		}
		
		public function resetFiles():void
		{
			this.pendingFiles = new Array();
			this.currentUploadFile = -1;
		}
		
		public function getNumberOfPendingFiles():Number
		{
			var count:Number = 0;
			for(var i:uint = 0; i < this.pendingFiles.length; i++){
				var uploadFile:UploadFile = this.pendingFiles[i];
				if(uploadFile.Status == UploadFile.STATUS_PENDING){
					count++;
				}
			}
			
			return count;
		}
		
		public function startUpload(pos, force = true):Boolean
		{
			if(pos >= this.pendingFiles.length || pos < 0){
				return false;
			}
			
			this.currentUploadFile = pos;
			var uploadFile = UploadFile(this.pendingFiles[pos]);
			if(uploadFile.Status != UploadFile.STATUS_PENDING && !force){
				return false;
			}
			
			uploadFile.startUpload();
			
			return true;
		}
		
		public function startNextPendingFile():Boolean
		{
			var pos:int = -1;
			
			if(this.currentUploadFile < 0)
				this.currentUploadFile = 0;
			
			for(var i:uint = this.currentUploadFile; i < this.pendingFiles.length; i++){
				var uploadFile:UploadFile = this.pendingFiles[i];
				if(uploadFile.Status == UploadFile.STATUS_PENDING){
					pos = i;
					break;
				}
			}
			
			if(pos >= 0){
				return this.startUpload(pos,false);
			}
			
			return false;
		}
		
		public function getFileStatus(pos:Number):Number
		{
			if(pos >= this.pendingFiles.length || pos < 0){
				return -1;
			}
			
			var uploadFile = UploadFile(this.pendingFiles[pos]);
			
			return uploadFile.Status;
		}
		
		public function addFileParameter(pos:Number, key:String, value:String):void
		{
			if(pos > this.pendingFiles.length || pos < 0)
				return;
				
			var uploadFile = UploadFile(this.pendingFiles[pos]);
			
			if(uploadFile){
				uploadFile.addRequestParameter(key,value);
			}
		}
		
		public function addFileFilter(str_label:String, str_filter:String):Boolean
		{
			this.openFilters.push(new FileFilter(str_label,str_filter));
			return true;
		}
		
		public function cancelFileUpload(pos):Boolean
		{
			if(pos > this.pendingFiles.length || pos < 0)
				return false;
		
			var uploadFile = UploadFile(this.pendingFiles[pos]);
			uploadFile.Status = UploadFile.STATUS_REMOVED;
		
			return true;
		}
	}
}